package com.skyd.core.common;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;

/**
 * 输入输出的相关操作
 * @author SkyD
 *
 */
public final class IO {
	
	/** 
     * 复制文件(以超快的速度复制文件) 
     *  
     * @param srcFile 
     *            源文件File 
     * @param destDir 
     *            目标目录File 
     * @param newFileName 
     *            新文件名 
     * @return 实际复制的字节数，如果文件、目录不存在、文件为null或者发生IO异常，返回-1 
     */  
    @SuppressWarnings("resource")
	public static long copyFile(File srcFile, File destDir, String newFileName) {  
        long copySizes = 0;  
        if (!srcFile.exists()) {  
            System.out.println("源文件不存在");  
            copySizes = -1;  
        } else if (!destDir.exists()) {  
            System.out.println("目标目录不存在");  
            copySizes = -1;  
        } else if (newFileName == null) {  
            System.out.println("文件名为null");  
            copySizes = -1;  
        } else {  
            try {  
                FileChannel fcin = new FileInputStream(srcFile).getChannel();  
                FileChannel fcout = new FileOutputStream(new File(destDir,newFileName)).getChannel();  
                long size = fcin.size();  
                fcin.transferTo(0, fcin.size(), fcout);  
                fcin.close();  
                fcout.close();  
                copySizes = size;  
            } catch (FileNotFoundException e) {  
                e.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
        return copySizes;  
    }  

	/**
	 * 创建目录，如果目录已存在则不执行操作
	 * @param path 目录路径
	 * @param isMultistageMode 是否为多级模式。如果为是则会自动创建上级各层次目录；否则只创建目标目录，父目录不存在时抛出异常。
	 * @return 是否执行了创建行为
	 */
	public static boolean createDir(String path,boolean isMultistageMode) {
		File f = new File(path);
		if(!f.exists()){
			return isMultistageMode?f.mkdirs():f.mkdir();		
		}
		return false;
	}
	
	/**
	 * 创建目录的子目录
	 * @param path 目录路径
	 * @param subdirname 子目录名称
	 * @return 子目录路径
	 */
	public static String createSubDir(String path,String subdirname){
		String s = combinationPath(path,subdirname);
		createDir(s, false);
		return s;
	}
	
	/**
	 * 组合路径
	 * @param path 目录路径
	 * @param subpath 子路径
	 * @return 组合后的路径
	 */
	public static String combinationPath(String path,String subpath){
		File f = new File(path);
		return	(f.getPath()+"/"+subpath).replace('\\', '/');
	}
	
	/**
	 * 取得压缩包中的 文件列表(文件夹,文件自选)
	 * @param zipFileString		压缩包名字
	 * @param bContainFolder	是否包括 文件夹
	 * @param bContainFile		是否包括 文件
	 * @return
	 * @throws Exception
	 */
	public static java.util.List<java.io.File> getZipFileList(String zipFileString, boolean bContainFolder, boolean bContainFile)throws Exception {
		
		android.util.Log.v("XZip", "GetFileList(String)");
		
		java.util.List<java.io.File> fileList = new java.util.ArrayList<java.io.File>();
		java.util.zip.ZipInputStream inZip = new java.util.zip.ZipInputStream(new java.io.FileInputStream(zipFileString));
		java.util.zip.ZipEntry zipEntry;
		String szName = "";
		
		while ((zipEntry = inZip.getNextEntry()) != null) {
			szName = zipEntry.getName();
		
			if (zipEntry.isDirectory()) {
		
				// get the folder name of the widget
				szName = szName.substring(0, szName.length() - 1);
				java.io.File folder = new java.io.File(szName);
				if (bContainFolder) {
					fileList.add(folder);
				}
		
			} else {
				java.io.File file = new java.io.File(szName);
				if (bContainFile) {
					fileList.add(file);
				}
			}
		}//end of while
		
		inZip.close();
		
		return fileList;
	}

	/**
	 * 解压一个压缩文档 到指定位置
	 * @param zipFileString	压缩包的名字
	 * @param outPathString	指定的路径
	 * @throws Exception
	 */
	public static void unZipToFolder(InputStream zipFile, String outPathString)throws Exception {
		java.util.zip.ZipInputStream inZip = new java.util.zip.ZipInputStream(zipFile);
		java.util.zip.ZipEntry zipEntry;
		String szName = "";
		
		while ((zipEntry = inZip.getNextEntry()) != null) {
			szName = zipEntry.getName();
		
			if (zipEntry.isDirectory()) {
		
				// get the folder name of the widget
				szName = szName.substring(0, szName.length() - 1);
				java.io.File folder = new java.io.File(outPathString + java.io.File.separator + szName);
				folder.mkdirs();
		
			} else {
		
				java.io.File file = new java.io.File(outPathString + java.io.File.separator + szName);
				file.createNewFile();
				// get the output stream of the file
				java.io.FileOutputStream out = new java.io.FileOutputStream(file);
				int len;
				byte[] buffer = new byte[1024];
				// read (len) bytes into buffer
				while ((len = inZip.read(buffer)) != -1) {
					// write (len) byte from buffer at the position 0
					out.write(buffer, 0, len);
					out.flush();
				}
				out.close();
			}
		}//end of while
		
		inZip.close();
	
	}//end of func
	

	/**
	 * 压缩文件,文件夹
	 * @param srcFileString	要压缩的文件/文件夹名字
	 * @param zipFileString	指定压缩的目的和名字
	 * @throws Exception
	 */
	public static void zipFolder(String srcFileString, String zipFileString)throws Exception {
		android.util.Log.v("XZip", "ZipFolder(String, String)");
		
		//创建Zip包
		java.util.zip.ZipOutputStream outZip = new java.util.zip.ZipOutputStream(new java.io.FileOutputStream(zipFileString));
		
		//打开要输出的文件
		java.io.File file = new java.io.File(srcFileString);

		//压缩
		zipFiles(file.getParent()+java.io.File.separator, file.getName(), outZip);
		
		//完成,关闭
		outZip.finish();
		outZip.close();
	
	}//end of func
	
	/**
	 * 压缩文件
	 * @param folderString
	 * @param fileString
	 * @param zipOutputSteam
	 * @throws Exception
	 */
	private static void zipFiles(String folderString, String fileString, java.util.zip.ZipOutputStream zipOutputSteam)throws Exception{
		android.util.Log.v("XZip", "ZipFiles(String, String, ZipOutputStream)");
		
		if(zipOutputSteam == null)
			return;
		
		java.io.File file = new java.io.File(folderString+fileString);
		
		//判断是不是文件
		if (file.isFile()) {

			java.util.zip.ZipEntry zipEntry =  new java.util.zip.ZipEntry(fileString);
			java.io.FileInputStream stream = new java.io.FileInputStream(file);
			zipOutputSteam.putNextEntry(zipEntry);
			
			int len;
			byte[] buffer = new byte[4096];
			
			while((len=stream.read(buffer)) != -1)
			{
				zipOutputSteam.write(buffer, 0, len);
			}
			
			zipOutputSteam.closeEntry();
			stream.close();
		}
		else {
			
			//文件夹的方式,获取文件夹下的子文件
			String fileList[] = file.list();
			
			//如果没有子文件, 则添加进去即可
			if (fileList.length <= 0) {
				java.util.zip.ZipEntry zipEntry =  new java.util.zip.ZipEntry(fileString+java.io.File.separator);
				zipOutputSteam.putNextEntry(zipEntry);
				zipOutputSteam.closeEntry();				
			}
			
			//如果有子文件, 遍历子文件
			for (int i = 0; i < fileList.length; i++) {
				zipFiles(folderString, fileString+java.io.File.separator+fileList[i], zipOutputSteam);
			}//end of for
	
		}//end of if
		
	}//end of func
}
